/*
 * @(#)EmailRuleEngineHelper.java
 *
 * Copyright (c) 2003 DCIVision Ltd
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of DCIVision
 * Ltd ("Confidential Information").  You shall not disclose such Confidential
 * Information and shall use it only in accordance with the terms of the license
 * agreement you entered into with DCIVision Ltd.
 */
package com.dcivision.dms.core;

import java.util.Hashtable;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.dcivision.alert.bean.UpdateAlert;
import com.dcivision.dms.web.MaintEmailArchiveRuleForm;
import com.dcivision.framework.GlobalConstant;
import com.dcivision.framework.MessageResourcesFactory;
import com.dcivision.framework.TextUtility;
import com.dcivision.framework.Utility;
import com.dcivision.rules.RuleOperationConstant;

/**
 * <p> Class Name: EmailRuleEngineHelper</p>
 * <p> Decription: This class is when edit and new rule, offer some method.</p>
 * 
 * 
 * @author        Tony Chen
 * @company       DCIVision Limited
 * @creation date 05/09/2005
 * @version       $Revision: 1.26.4.1 $
 */
public class EmailRuleEngineHelper {
  protected Log log = LogFactory.getLog(this.getClass().getName());
  
  private Locale locale = null;
  private String language = null;
  private String workflowList = null;
  private String changeTextBoxID = null;
  private StringBuffer ruleDescript = new StringBuffer();
  private Hashtable condValueHt = new Hashtable();
  private Hashtable condDescHt = new Hashtable();
  
  private Hashtable actionValueHt = new Hashtable();
  private Hashtable actionDescHt = new Hashtable();
  
  private Hashtable conditionHt = new Hashtable();
  private Hashtable optionType1Ht = new Hashtable();
  private Hashtable optionType2Ht = new Hashtable();
  private Hashtable actionCategoryItemHt = new Hashtable();
  private Hashtable notifyItemHt = new Hashtable();
  private Hashtable workflowListHt = new Hashtable();
  
  private String[] condValueArr = new String[4];
  private String[] condDescArr = new String[4];
  
  private String[] actionValueArr = new String[3];
  private String[] actionDescArr = new String[3];
  
  public static final String SPILT_1 = "##";
  public static final String SPILT_2 = "$$";
  private final String EMAIL_CHAR = "@";
  
  private int condSeq = 0;
  private final int RULE_ITEM_TOTAL = 100;
  private String CONTEXT_PATH = "";
  private boolean displayCondPlus = false;
  
  private String AND = null;
  private String OR = null;
  private String IF = null;
  private String THEN = null;  
  private String SELECT_CONDITION = null;
  private String SELECT_JUDGEMENT = null;
  private String SELECT_ACTION = null;
  private String SELECT_NOTIFY = null;
  private String SELECT_TARGET = null;
  private String SELECT_WORKFLOW = null;
  private String SELECT_USER = null;
  private String SELECT_FOLDER_PATH = null;
  private String SELECT_SUBMITTER = null;
  private String BY = null;
  private String HAS_ATTACHMENT = null;
  private String CONTAINS = null;
  private String selectJudgement = null;
  private String ruleType;
 
  /**
   * get the text box
   * @param value
   * @param condSeq
   * @param changeTextBox
   * @return String
   */
  private String getTextBox( String value, String condSeq, boolean changeTextBox ){
    String textBox =  "";
    if (Utility.isEmpty(value)) { 
      value = "";
      textBox = "&nbsp;&nbsp;<input type=\'text\' name=\'value\' value=\'" + value + "\' onkeydown=\'javascrit: { if (event.keyCode==13)  checkValue(this, " + condSeq + "); }\' onBlur=\'checkValue(this, " + condSeq + ")\' size=\'20\' style=\"Border-top-width=0; Border-right-width=0; Border-left-width=0; Border-botto m-width=1\">";
    } else {      

      if (!changeTextBox) {
        if (EMAIL_CHAR.equals(value)) {
          textBox = "&nbsp;&nbsp;<a href=\"javascript:void(0);\" onclick=\"return changeTextBox(\'" + condSeq + "\')\"><font color=\'black\'><b>" + value + "</b></font></a>";
        } else {
          textBox = "&nbsp;&nbsp;<a href=\"javascript:void(0);\" onclick=\"return changeTextBox(\'" + condSeq + "\')\"><font color=\'blue\'>" + value + "</font></a>";
        }
      } else {
        textBox = "&nbsp;&nbsp;<input type=\'text\' name=\'value\' value=\'" + value + "\'  onkeydown=\'javascrit: { if (event.keyCode==13) checkValue(this, " + condSeq + "); }\' onBlur=\'checkValue(this, " + condSeq + ")\' size=\'20\' style=\"Border-top-width=0; Border-right-width=0; Border-left-width=0; Border-botto m-width=1\">";
      }
    }  
      
    return textBox;
  }
  
  /**
   * get condition 
   * @param language
   * @return String[][]
   */
  private String[][] getCondition(String language){
    Locale loc = Utility.getLocaleByString(language);
    String[][] itemArray = {
        {MessageResourcesFactory.getMessage(loc, "email_archive.rule.subject"), MaintEmailArchiveRuleForm.CRITERION_SUBJECT},
        {MessageResourcesFactory.getMessage(loc, "email_archive.rule.message"), MaintEmailArchiveRuleForm.CRITERION_MESSAGE},
        {MessageResourcesFactory.getMessage(loc, "email_archive.rule.messagebody"), MaintEmailArchiveRuleForm.CRITERION_MESSAGE_BODY},
        {MessageResourcesFactory.getMessage(loc, "email_archive.rule.to"), MaintEmailArchiveRuleForm.CRITERION_EMAILTO},
        {MessageResourcesFactory.getMessage(loc, "email_archive.rule.cc"), MaintEmailArchiveRuleForm.CRITERION_EMAILCC},
        {MessageResourcesFactory.getMessage(loc, "email_archive.rule.from"), MaintEmailArchiveRuleForm.CRITERION_EMAILFROM}
      };
    return itemArray;  
  }
  
  /**
   * get option type 1
   * @param language
   * @return String[][]
   */
  private String[][] getOptionType1(String language){
    Locale loc = Utility.getLocaleByString(language);
    String[][] itemArray = {
        {MessageResourcesFactory.getMessage(loc, "email_archive.rule.is"), RuleOperationConstant.PREDICATE_TYPE_EQUAL_IGNORE_CASE},
        {MessageResourcesFactory.getMessage(loc, "email_archive.rule.contains"), RuleOperationConstant.PREDICATE_TYPE_CONTAINES}        
      };
    return itemArray;  
  }  
  
  /**
   * get option type 2
   * @param language
   * @return String[][]
   */
  private String[][] getOptionType2(String language){
    Locale loc = Utility.getLocaleByString(language);
    String[][] itemArray = {
        {MessageResourcesFactory.getMessage(loc, "email_archive.rule.is"), RuleOperationConstant.PREDICATE_TYPE_CONTAINES_EQUALS},
        {MessageResourcesFactory.getMessage(loc, "email_archive.rule.contains"), RuleOperationConstant.PREDICATE_TYPE_CONTAINES_ARRAY}        
      };
    return itemArray;  
  } 
  
  /**
   * get action category item
   * @param language
   * @return String[][]
   */
  private String[][] getActionCategoryItem(String language){
    Locale loc = Utility.getLocaleByString(language);
    String[][] itemArray = {
        {MessageResourcesFactory.getMessage(loc, "email_archive.rule.notyfy_me"), MaintEmailArchiveRuleForm.ACTION_NOTIFY_ME},
        {MessageResourcesFactory.getMessage(loc, "email_archive.rule.route_to"), MaintEmailArchiveRuleForm.ACTION_RUTE_TO},        
        {MessageResourcesFactory.getMessage(loc, "email_archive.rule.start_workflow"), MaintEmailArchiveRuleForm.ACTION_START_WORKFLOW}
      };
    return itemArray;  
  }  
  
  /**
   * get notify item
   * @param language 
   * @return String[][]
   */
  private String[][] getNotifyItem(String language){
    Locale loc = Utility.getLocaleByString(language);
    String[][] itemArray = {
        {MessageResourcesFactory.getMessage(loc, "email_archive.rule.by_email"), UpdateAlert.EMAIL_NOTIFICATION},
        {MessageResourcesFactory.getMessage(loc, "email_archive.rule.by_system_message"), UpdateAlert.SYSTEM_NOTIFICATION},        
        {MessageResourcesFactory.getMessage(loc, "email_archive.rule.by_email_system"), UpdateAlert.EMAIL_NOTIFICATION + RuleOperationConstant.SPLIT_STRING + UpdateAlert.SYSTEM_NOTIFICATION}
      };
    return itemArray;  
  }  
  
  /**
   * create the condition div
   * @param language
   * @return
   */
  private String getSelectCondition(String language){
    String[][]  itemArr = this.getCondition(language);
    StringBuffer strBuff = new StringBuffer();
    
    strBuff.append(" <a href=\'#\' onclick=\"displayDiv(\'conditionDiv\', true)\" onMouseOut=\"return nd();\"  ><font color=\'blue\'>" + SELECT_CONDITION + "</font></a>");
    strBuff.append(" <!-- Condition Div Begin  -->");
    strBuff.append(" <div id=\"conditionDiv\" \" style=\'visibility:hidden;width:120;position:absolute; left:100px; top:100px;  z-index:5;\' border=\"0\" >");
    strBuff.append(" <table bgcolor=\"#727272\"  width=\"150\" cellpadding=\"0\" cellspacing=\"1\" border=\"0\">");
    strBuff.append("   <tr><td bgcolor=\"#FFFFFF\" valign=\"top\" > ");
    strBuff.append("     <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" align=\"left\" >");
    
    for (int i=0; i<itemArr.length; i++) {   
    	strBuff.append(" <tr onmouseover=\"SetTableRowColor(this, 0, \'over\', 44);\" onmouseout=\"SetTableRowColor(this, 0, \'out\', 44);\" >");
    	strBuff.append(" <td onclick=\"selectedCondition(\'" + itemArr[i][1] + "\', \' " + itemArr[i][0] + "\', \'conditionDiv\')\">");
    	strBuff.append(itemArr[i][0]);                
    	strBuff.append(" </td></tr>");
    }
    strBuff.append("     </table>"); 
    strBuff.append("   </td></tr>");
    strBuff.append(" </table>");
    strBuff.append(" </div>");
    strBuff.append("<!-- Condition Div End    -->");
    
    return strBuff.toString();
  }
  
  /**
   * get the judgement div
   * @param language
   * @return
   */
  private String getOption2Item(String language, boolean isOptionType1){
    String[][] option = null;
    if (isOptionType1) {
      option = this.getOptionType1(language);
    } else {
      option = this.getOptionType2(language);
    }
    StringBuffer strBuff = new StringBuffer();        
    strBuff.append("<!-- Judgement Div Begin  -->"); 
    strBuff.append("<div id=\"judgementDiv\" style=\'visibility:hidden; position:absolute; left:290px; top:360px;  z-index:5;\'  border=\"0\" >"); 
    strBuff.append(" <table bgcolor=\"#727272\"  width=\"80\" cellpadding=\"0\" cellspacing=\"1\" border=\"0\">"); 
    strBuff.append("   <tr><td bgcolor=\"#FFFFFF\" valign=\"top\">"); 
    strBuff.append("     <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" align=\"left\" >"); 
    
    for (int i=0; i<option.length; i++) {    
    	strBuff.append("      <tr onmouseover=\"SetTableRowColor(this, 0, \'over\', 44);\" onmouseout=\"SetTableRowColor(this, 0, \'out\', 44);\" >"); 
    	strBuff.append("        <td onclick=\"selectedJudgement(\'" + option[i][1] + "\', \'" + option[i][0] + "\', \'judgementDiv\')\">"); 
    	strBuff.append( option[i][0]);                 
    	strBuff.append("      </td></tr>"); 
    } 
    strBuff.append("     </table> "); 
    strBuff.append("   </td></tr>"); 
    strBuff.append("   </table>"); 
    		strBuff.append(" </div>"); 
    strBuff.append("<!-- Judgement Div End    -->"); 
    return strBuff.toString();
  }
  
  /**
   * get action Div
   * @param language
   * @return String
   */
  private String generateActionDiv(String language){
    String[][]  itemArr = this.getActionCategoryItem(language);
    StringBuffer strBuff = new StringBuffer();
    
    strBuff.append(" <a href=\'#\' onclick=\"displayDiv(\'actionDiv\', true)\" onMouseOut=\"return nd();\"  ><font color=\'blue\'>" + SELECT_ACTION + "</font></a>");
    strBuff.append(" <!-- Action Div Begin  -->");
    strBuff.append(" <div id=\"actionDiv\" style=\'visibility:hidden; position:absolute; left:290px; top:360px;z-index:5;width:100;\'  border=\"0\" >");
    strBuff.append(" <table bgcolor=\"#727272\"  width=\"150\" cellpadding=\"0\" cellspacing=\"1\" border=\"0\">");
    strBuff.append("   <tr><td bgcolor=\"#FFFFFF\" valign=\"top\">");
    strBuff.append("     <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" align=\"left\" >");
    
    for (int i=0; i<itemArr.length; i++) {   
      strBuff.append(" <tr onmouseover=\"SetTableRowColor(this, 0, \'over\', 44);\" onmouseout=\"SetTableRowColor(this, 0, \'out\', 44);\" >");
      strBuff.append(" <td onclick=\"selectedAction(\'" + itemArr[i][1] + "\', \' " + itemArr[i][0] + "\', \'actionDiv\')\">");
      strBuff.append(itemArr[i][0]);                
      strBuff.append(" </td></tr>");
    }
    strBuff.append("     </table>"); 
    strBuff.append("   </td></tr>");
    strBuff.append(" </table>");
    strBuff.append(" </div>");
    strBuff.append("<!-- Action Div End    -->");
    
    return strBuff.toString();
  }
  
  /**
   * generate notify div
   * @param language
   * @param value
   * @param ID
   * @return String
   */
  private String generateNotifyDiv(String language, String value, String ID){
    String[][]  itemArr = this.getNotifyItem(language);
    StringBuffer strBuff = new StringBuffer();
    
    strBuff.append(" <a href=\'#\' onclick=\"displayDiv(\'notifyDiv" + ID + "\', true)\" onMouseOut=\"return nd();\"  ><font color=\'blue\'>" + value + "</font></a>");
    strBuff.append(" <!-- Notify Div Begin  -->");
    strBuff.append(" <div id=\"notifyDiv" + ID + "\" style=\'visibility:hidden; position:absolute; left:290px; top:360px;z-index:5;width:100;\'  border=\"0\" >");
    strBuff.append(" <table bgcolor=\"#727272\"  width=\"180\" cellpadding=\"0\" cellspacing=\"1\" border=\"0\">");
    strBuff.append("   <tr><td bgcolor=\"#FFFFFF\" valign=\"top\">");
    strBuff.append("     <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" align=\"left\" >");
    
    for (int i=0; i<itemArr.length; i++) {   
      strBuff.append(" <tr onmouseover=\"SetTableRowColor(this, 0, \'over\', 44);\" onmouseout=\"SetTableRowColor(this, 0, \'out\', 44);\" >");
      strBuff.append(" <td onclick=\"addAnAction(\'" + itemArr[i][1] + "\', \' " + itemArr[i][0] + "\', \'notifyDiv" + ID + "\', " + ID + ")\">");
      strBuff.append(itemArr[i][0]);                
      strBuff.append(" </td></tr>");
    }
    strBuff.append("     </table>"); 
    strBuff.append("   </td></tr>");
    strBuff.append(" </table>");
    strBuff.append(" </div>");
    strBuff.append("<!-- Notify Div End    -->");
    
    return strBuff.toString();
  }
  
  /**
   * generate workflow div
   * @param workflow
   * @param value
   * @param ID
   * @return String
   */
  private String generateWorkflowDiv(String workflow, String value, String ID){    
    StringBuffer strBuff = new StringBuffer();     
    String[] tempObj = TextUtility.splitString(workflow, SPILT_2); 
    
    strBuff.append(" <a href=\'#\' onclick=\"displayDiv(\'workflowDiv" + ID + "\', true)\" onMouseOut=\"return nd();\"  ><font color=\'blue\'>" + value + "</font></a>");
    strBuff.append(" <!-- Workflow Div Begin  -->");
    strBuff.append(" <div id=\"workflowDiv" + ID + "\" style=\'visibility:hidden; position:absolute; left:290px; top:360px;width:100;height:100;OVERFLOW-Y:auto;border-width:1;border-style:ridge;border-color:#727272'\'  border=\"0\" >");
//    strBuff.append(" <input type=\'hidden\' name=\'condition\'>");
    strBuff.append(" <table bgcolor=\"#727272\"  width=\"180\" cellpadding=\"0\" cellspacing=\"1\" border=\"0\">");
    strBuff.append("   <tr><td bgcolor=\"#FFFFFF\" valign=\"top\">");
    strBuff.append("     <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" align=\"left\" >");
      
    if (!Utility.isEmpty(tempObj)) {
      for (int i = 0; i < tempObj.length; i++) {
        String[] itemArr = TextUtility.splitString(tempObj[i], SPILT_1);
        strBuff
            .append(" <tr onmouseover=\"SetTableRowColor(this, 0, \'over\', 44);\" onmouseout=\"SetTableRowColor(this, 0, \'out\', 44);\" >");
        strBuff.append(" <td onclick=\"selectSubmitter(\'" + itemArr[0]
            + "\', \' " + itemArr[1] + "\', \'workflowDiv" + ID + "\', " + ID
            + ")\">");
        strBuff.append(itemArr[1]);
        strBuff.append(" </td></tr>");
      }
    }
    strBuff.append("     </table>"); 
    strBuff.append("   </td></tr>");
    strBuff.append(" </table>");
    strBuff.append(" </div>");
    strBuff.append("<!-- Workflow Div End    -->");
    
    return strBuff.toString();
  }
  
  /**
   * get user picker
   * @param showValue
   * @param ID
   * @return String
   */  
  private String getUserPicker(String showValue, String ID){
    StringBuffer strBuff = new StringBuffer();   
    String userID = "";
    String groupID = "";
    String roleID = "";
    String displayName = "";
    
    if(!Utility.isEmpty(showValue)){
      String[] tmpArr = TextUtility.splitString(showValue, RuleOperationConstant.SPLIT_COMMA);
      for(int i = 0; i < tmpArr.length; i++){
        if(tmpArr[i].indexOf("U") > -1){
          if(!Utility.isEmpty(userID)){
            userID += RuleOperationConstant.SPLIT_COMMA;
          }
          userID += (tmpArr[i]).substring(2);//U:1
        
        } else if(tmpArr[i].indexOf("G") > -1){
          if(!Utility.isEmpty(groupID)){
            groupID += RuleOperationConstant.SPLIT_COMMA;
          }
          groupID += (tmpArr[i]).substring(2);//G:1
          
        } else if(tmpArr[i].indexOf("R") > -1){
          if(!Utility.isEmpty(roleID)){
            roleID += RuleOperationConstant.SPLIT_COMMA;
          }
          roleID += (tmpArr[i]).substring(2);//R:1
          
        } 
      }
    }
    
    //get the display name 
    EmailRuleEngineHandle handle = new EmailRuleEngineHandle();
    displayName = handle.getUserPickerString(userID, groupID, roleID);  
    
    if (!Utility.isEmpty(displayName) ) {
    	strBuff.append("/<a href=\"javascript:void(0);\" onclick=\"return OpenCenteredPopup(\'" + CONTEXT_PATH + "/dms/MaintDmsPopComplex.do?userID=" + userID + "&groupID=" + groupID + "&roleID=" + roleID + "&index=0&ID=" + ID + "&passValue=\', \'DCIVisionPopupDmsComplexPanel\', 520, 500, \'scrollbars=yes,resizable=yes\');\"> <font color=\'blue\'>" + displayName + "</font></a> ");
      
    } else { 
      displayName = SELECT_USER;
      strBuff.append("/<a href=\"javascript:void(0);\" onclick=\"return OpenCenteredPopup(\'" + CONTEXT_PATH + "/dms/MaintDmsPopComplex.do?userID=" + userID + "&groupID=" + groupID + "&roleID=" + roleID + "&index=0&ID=" + ID + "&passValue=\', \'DCIVisionPopupDmsComplexPanel\', 520, 500, \'scrollbars=yes,resizable=yes\');\"><font color=\'blue\'>" + displayName + "</font></a> ");
    }
    return strBuff.toString();
  }
  
  private String getEmailInputText_(String showValue, String ID){
    StringBuffer strBuff = new StringBuffer();   
    if ( !Utility.isEmpty(showValue)) {      
      //strBuff.append("<input type=\'text\' name=\'value\' value=\'" + showValue + "\' onBlur=\'checkValue(this, \"-1\")\' size=\'20\' style=\"Border-top-width=0; Border-right-width=0; Border-left-width=0; Border-botto m-width=1\">");
//      strBuff.append("<a href=\"javascript:void(0);\">" + showValue + "</a>" );
      strBuff.append("&nbsp;&nbsp;<a href=\"javascript:void(0);\" onclick=\"return changeTextBox(\'" + ID + "\')\"> <font color=\'blue\'>" + showValue + "</font></a>");
    } else {             
      strBuff.append("<input type=\'text\' name=\'value\' value=\'" + "\' onBlur=\'checkValue(this, \"-1\")\' size=\'20\' style=\"Border-top-width=0; Border-right-width=0; Border-left-width=0; Border-botto m-width=1\">");
      
    }
    return strBuff.toString();
    
  }
 
  /**
   * get folder picker
   * @param rootID
   * @param parentID
   * @param ID
   * @return
   */
  private String getFolderPicker(String rootID, String parentID, String ID){
    StringBuffer strBuff = new StringBuffer();   
    String folderPath = "";
    if (!Utility.isEmpty(parentID)) {
      EmailRuleEngineHandle handle = new EmailRuleEngineHandle();
      folderPath = handle.getFolderPath(rootID, parentID);  
    }
    if (!Utility.isEmpty(folderPath)) {
      strBuff.append("<a href=\"#\" onClick=\"popupFolderSelectionPanel(\'" + rootID + "\', \'" + parentID + "\', \'locationPath_emailArchive\', \'rootID_emailArchive\', \'parentID_emailArchive\',\'\',\'false\',\'false\',\'false\',\'\',\'0\',\'false\',\'false\',\'false\'," + ID + ",\'true\',\'\',\'\',\'"+this.ruleType+"\'); \"><font color=\'blue\'> " + folderPath + "</font></a> ");
      
    } else {  
      folderPath = SELECT_FOLDER_PATH;
      strBuff.append("<a href=\"#\" onClick=\"popupFolderSelectionPanel(\'" + rootID + "\', \'" + parentID + "\', \'locationPath_emailArchive\', \'rootID_emailArchive\', \'parentID_emailArchive\',\'\',\'false\',\'false\',\'false\',\'\',\'0\',\'false\',\'false\',\'false\'," + ID + ",\'true\',\'\',\'\',\'"+this.ruleType+"\'); \"><font color=\'blue\'> " + folderPath + "</font></a> ");       
    }
    return strBuff.toString();
  }
  
  /**
   * get workflow list
   * @param workflowList
   * @return String
   */
  private String getWorkflowList( String workflowList ){
    StringBuffer strBuff = new StringBuffer();   
    String[] tempArr = TextUtility.splitString(workflowList, "$$"); 
    
    strBuff.append("<select name=\"actionS0\" onChange=\"workflowChange(0);\"> " );
     
    for (int i = 0; i <tempArr.length; i++ ) {
      String[] tmpObj = TextUtility.splitString(tempArr[i], "|");
      strBuff.append("<option value=\" " + tmpObj[0] + "\" > " + tmpObj[1] + "</option>"); 
    }      
      
    strBuff.append("</select>");
    return strBuff.toString();
  }
  
  /**
   * get the option 1
   * @param language
   * @param isAnd
   * @return
   */
  public String getOption1(String language, boolean isAnd){
    condDescArr[0] = this.getSelectCondition(language);    
    this.displayCondPlus = false;
    return this.getOldCondition(isAnd);
  }
  
  /**
   * get the option 2
   * @param optionValue
   * @param optionDesc
   * @param language
   * @param isAnd
   * @return
   */
  public String getOption2(String optionValue, String optionDesc, String language, boolean isAnd){
    StringBuffer option = new StringBuffer();
    //record the option.
    condValueArr[0] = optionValue;
    condDescArr[0] = optionDesc;
        
    if(MaintEmailArchiveRuleForm.CRITERION_MESSAGE.equals(optionValue) ) {
      condValueArr[1] = RuleOperationConstant.PREDICATE_TYPE_GREATER_THAN_OR_EQUAL;
      condDescArr[1] = HAS_ATTACHMENT;
      
      condValueArr[2] = "1";
      condDescArr[2] = "&nbsp;";
      this.displayCondPlus = true;
      this.recordCondition();
     
    } else if( MaintEmailArchiveRuleForm.CRITERION_MESSAGE_BODY.equals(optionValue) ) {  
      condValueArr[1] = RuleOperationConstant.PREDICATE_TYPE_CONTAINES;
      condDescArr[1] = CONTAINS;
      
      condDescArr[2] = this.getTextBox("", "-1", false); //textBox;
      this.displayCondPlus = false;
      
    } else if (MaintEmailArchiveRuleForm.CRITERION_SUBJECT.equals(optionValue) ) {  
      option.append(selectJudgement);
      option.append( this.getOption2Item(language, true) );        
      condDescArr[1] = option.toString();
      this.displayCondPlus = false;
      
    } else {
      option.append(selectJudgement);
      option.append( this.getOption2Item(language, false) );        
      condDescArr[1] = option.toString();
      this.displayCondPlus = false;
    }      
    
    return this.getOldCondition(isAnd);
  }
  
  /**
   * get the option 3
   * @param optionValue
   * @param optionDesc
   * @param isAnd
   * @return
   */
  public String getOption3(String optionValue, String optionDesc, boolean isAnd){
    StringBuffer option = new StringBuffer();
    //record the option.
    condValueArr[1] = optionValue;
    condDescArr[1] = optionDesc;
        
    if(MaintEmailArchiveRuleForm.CRITERION_SUBJECT.equals(condValueArr[0]) ) {
      option.append(this.getTextBox("", "-1", false));     
      condDescArr[2] = option.toString();   
      this.displayCondPlus = false;

    } else if (MaintEmailArchiveRuleForm.CRITERION_EMAILTO.equals(condValueArr[0])
        || MaintEmailArchiveRuleForm.CRITERION_EMAILCC.equals(condValueArr[0])
        || MaintEmailArchiveRuleForm.CRITERION_EMAILFROM.equals(condValueArr[0]) ) {      
//      condDescArr[2] = this.getEmailInputText("", "-1");
      condDescArr[2] = this.getTextBox("", "-1", false);
      condDescArr[3] = this.getUserPicker("", "-1");
      this.displayCondPlus = false;
    
    }
    
    return this.getOldCondition(isAnd);
  }
   
  /**
   * add a conditon to list.
   * @param optionValue
   * @param optionDesc
   * @return
   */
  public String addCondition(String optionValue, String optionDesc, boolean isAnd, String ID){
    if ("-1".equals(ID)){
      if (MaintEmailArchiveRuleForm.CRITERION_EMAILTO.equals(condValueArr[0])
          || MaintEmailArchiveRuleForm.CRITERION_EMAILCC.equals(condValueArr[0])
          || MaintEmailArchiveRuleForm.CRITERION_EMAILFROM.equals(condValueArr[0]) ) {        
        
        if (optionValue.indexOf(RuleOperationConstant.SPLIT_COLON) > -1) {
          condValueArr[3] = optionValue;
          condDescArr[3] = optionDesc;
          if (Utility.isEmpty(condValueArr[2])) {
            condValueArr[2] = EMAIL_CHAR;
            condDescArr[2] = EMAIL_CHAR;  
          }
        } else {
          condValueArr[2] = optionValue;
          condDescArr[2] = optionDesc;  
        }
        
      } else {
      	//record the option
      	condValueArr[2] = optionValue;
      	condDescArr[2] = optionDesc;   
      }
      
      this.recordCondition();
      
    } else {    
      String[] tmpArr = (String[])this.condValueHt.get(ID); 
      String[] tmpArr2 = (String[])this.condDescHt.get(ID);
      
      if (MaintEmailArchiveRuleForm.CRITERION_EMAILTO.equals(tmpArr[0])
          || MaintEmailArchiveRuleForm.CRITERION_EMAILCC.equals(tmpArr[0])
          || MaintEmailArchiveRuleForm.CRITERION_EMAILFROM.equals(tmpArr[0]) ) {        
        
        if (optionValue.indexOf(RuleOperationConstant.SPLIT_COLON) > -1) {
          tmpArr[3] = optionValue;
          tmpArr2[3] = optionDesc;
        } else {
          tmpArr[2] = optionValue;
          tmpArr2[2] = optionDesc;  
        }
        
        
      }  else {      
      	tmpArr[2] = optionValue;
        tmpArr2[2] = optionDesc;        
      	
      }
      
      if (condValueHt.containsKey(ID)) {
        this.condValueHt.remove(ID);
      }       
      this.condValueHt.put(ID, tmpArr);
      
      if (condDescHt.containsKey(ID)) {
        this.condDescHt.remove(ID);
      }        
      this.condDescHt.put(ID, tmpArr2);
    }
    
    return this.getOldCondition(isAnd);
  }
  
  /**
   * record a conditon.   
   */
  private void recordCondition(){
    log.debug("condValueArr: "+condValueArr[0]);
    
    String[] tmpValueArr = new String[4];
    String[] tmpDescArr = new String[4];
    
    tmpValueArr[0] = condValueArr[0];
    tmpValueArr[1] = condValueArr[1];
    tmpValueArr[2] = condValueArr[2];
    tmpValueArr[3] = condValueArr[3];
        
    tmpDescArr[0] = condDescArr[0];
    tmpDescArr[1] = condDescArr[1];
    tmpDescArr[2] = condDescArr[2];
    tmpDescArr[3] = condDescArr[3];
    
    if ( !this.hasSameObject(condValueHt, this.RULE_ITEM_TOTAL, tmpValueArr) ) {
    	condSeq++; 
    	condValueHt.put(String.valueOf(condSeq), tmpValueArr);    
    	condDescHt.put(String.valueOf(condSeq), tmpDescArr);
    }
    condValueArr = new String[4];
    condDescArr = new String[4];
  }
  
  /**
   * new a Condition.
   * @param language
   * @param isAnd
   * @return
   */
  public String newCondition(String language, boolean isAnd){
    StringBuffer buffer = new StringBuffer();
   
    this.displayCondPlus = false;
    if (!Utility.isEmpty(condDescArr[0])) {
      this.recordCondition();
    }
    
    condDescArr[0] = this.getSelectCondition(language);    
    return this.getOldCondition(isAnd);
  }
  
  /**
   * display the old conditon
   * @param isAnd
   * @return
   */  
  public String getOldCondition(boolean isAnd){
    StringBuffer buffer = new StringBuffer();
    String addDeleteStr = null;    

    //check the same value
    this.mergeSameObject(condValueHt, this.RULE_ITEM_TOTAL);
    this.mergeSameObject(condDescHt, this.RULE_ITEM_TOTAL);
    
    int j = 0;    
    for (int i = 0; i < condSeq + 1; i++) {
      String tmpObj = String.valueOf(i); 
      if (condValueHt.containsKey(tmpObj)) {
        String[] tempArr = (String[])(condDescHt.get(tmpObj));
        String[] tempArr2 = (String[])(condValueHt.get(tmpObj));
        
        if (j > 0) {
          if (isAnd) {
            buffer.append(AND + "&nbsp;");
          } else {
            buffer.append(OR + "&nbsp;");
          }  
        }
        
        buffer.append(tempArr[0] + "&nbsp;&nbsp;" + tempArr[1] + "&nbsp;&nbsp;");
        
        
        if(MaintEmailArchiveRuleForm.CRITERION_SUBJECT.equals(tempArr2[0]) ||
            MaintEmailArchiveRuleForm.CRITERION_MESSAGE_BODY.equals(tempArr2[0])  ) {
          tempArr[2] = this.getTextBox(tempArr2[2], tmpObj, tmpObj.equals(this.changeTextBoxID) ); 
          if (tmpObj.equals(this.changeTextBoxID)) {
            this.changeTextBoxID = null;
          }
          buffer.append(tempArr[2]);  
          
        } else if (MaintEmailArchiveRuleForm.CRITERION_EMAILTO.equals(tempArr2[0])
            || MaintEmailArchiveRuleForm.CRITERION_EMAILCC.equals(tempArr2[0])
            || MaintEmailArchiveRuleForm.CRITERION_EMAILFROM.equals(tempArr2[0]) ) {        
                    
          tempArr[2] = this.getTextBox(tempArr2[2], tmpObj, tmpObj.equals(this.changeTextBoxID));
          if (tmpObj.equals(this.changeTextBoxID)) {
            this.changeTextBoxID = null;
          }
          
          tempArr[3] = this.getUserPicker(tempArr2[3], tmpObj);
          buffer.append(tempArr[2]);
          buffer.append(tempArr[3]);
          
        } else if (MaintEmailArchiveRuleForm.CRITERION_MESSAGE.equals(tempArr2[0])) {
          tempArr[1] = HAS_ATTACHMENT;
          tempArr[2] = "&nbsp;";
          buffer.append(tempArr[2]);  
        }
        
//        buffer.append(tempArr[2]);  
        
        buffer.append("&nbsp;&nbsp;&nbsp;&nbsp;<a href=\'#\' onclick=\'removeCondition(" + tmpObj + ")\'>[X]</a>");
        buffer.append("<br>");  
        j++;
      }else{
        if(MaintEmailArchiveRuleForm.CRITERION_SUBJECT.equals(condValueArr[0])  ||
            MaintEmailArchiveRuleForm.CRITERION_MESSAGE.equals(condValueArr[0]) || 
            MaintEmailArchiveRuleForm.CRITERION_MESSAGE_BODY.equals(condValueArr[0]) || 
            MaintEmailArchiveRuleForm.CRITERION_EMAILTO.equals(condValueArr[0]) ||
            MaintEmailArchiveRuleForm.CRITERION_EMAILCC.equals(condValueArr[0]) ||
            MaintEmailArchiveRuleForm.CRITERION_EMAILFROM.equals(condValueArr[0]) ){
          addDeleteStr = "&nbsp;&nbsp;&nbsp;&nbsp;<a href=\'#\' onclick=\'removeCondition(" + tmpObj + ")\'>[X]</a><br>";
        }
      }
      
    } 
    

    
    //===================================
    
    //add the last conditon
    if(!Utility.isEmpty(condDescArr[0])){
      if (!condDescHt.isEmpty()) {
        if (isAnd) {
          buffer.append(AND + "&nbsp;");
        } else {
          buffer.append(OR + "&nbsp;");
        }  
      }
      buffer.append(condDescArr[0] + "&nbsp;&nbsp;");
    }
    
    if(!Utility.isEmpty(condDescArr[1])){
      buffer.append(condDescArr[1] + "&nbsp;&nbsp;");
    }
    
    if(!Utility.isEmpty(condDescArr[2])){
      buffer.append(condDescArr[2] + "&nbsp;&nbsp;");
    }
    
    if(!Utility.isEmpty(condDescArr[3])){
      buffer.append(condDescArr[3] + "&nbsp;&nbsp;");
    }
    
    if(addDeleteStr!=null){
      buffer.append(addDeleteStr);
    }
    return buffer.toString();
  }
  
  
  /**
   * remove a condition.
   * @param itemSeq
   * @param isAnd
   * @return String
   */
  public String removeCondition(String itemSeq, boolean isAnd){
    StringBuffer buff = new StringBuffer();
    
    condValueHt.remove(itemSeq);
    condDescHt.remove(itemSeq);
    
    this.displayCondPlus = condValueHt.isEmpty(); 
    buff.append(this.getOldCondition(isAnd));
    
    return buff.toString();
  }
  
  
  //========================== action =================

  /**
   * get old action
   */  
  private String getOldAction(){
    StringBuffer buffer = new StringBuffer();          
        
    //Remove the same action
    this.mergeSameObject(actionValueHt, this.RULE_ITEM_TOTAL);
    
    int j = 0;    
    for (int i = 0; i < condSeq + 1; i++) {    
      String tmpObj = String.valueOf(i);
      if (actionValueHt.containsKey(tmpObj)) {
        String[] tempArr = (String[])(actionDescHt.get(tmpObj));
        String[] tempArr2 = (String[])(actionValueHt.get(tmpObj));
        
        if (j > 0) {        
          buffer.append(AND + "&nbsp;");        
        }       
        buffer.append(tempArr[0] + "&nbsp;&nbsp;");
        
        
        if (MaintEmailArchiveRuleForm.ACTION_NOTIFY_ME.equals( tempArr2[0] )){
          tempArr[1] = this.generateNotifyDiv(language, (String)this.notifyItemHt.get(tempArr2[1]), tmpObj ); 
          
        } else if (MaintEmailArchiveRuleForm.ACTION_RUTE_TO.equals( tempArr2[0] )){
          String[] valueArr = TextUtility.splitString(tempArr2[1], RuleOperationConstant.SPLIT_STRING);        
          tempArr[1] = this.getFolderPicker(valueArr[0], valueArr[1], tmpObj ); 
          
        } else if (MaintEmailArchiveRuleForm.ACTION_START_WORKFLOW.equals( tempArr2[0] )){
          //init WorkflowList Hashtable        
          String[] workflowArr = TextUtility.splitString(workflowList, SPILT_2);
          for (int n = 0; n < workflowArr.length; n++) {
            String[] tmpArr = TextUtility.splitString(workflowArr[n], SPILT_1);
            workflowListHt.put(tmpArr[0], tmpArr[1]);
          }        
          tempArr[1] = this.generateWorkflowDiv(workflowList, (String)workflowListHt.get(tempArr2[1]), tmpObj );
          
          //tempArr[2] = "";
        }      
        
        
        buffer.append(tempArr[1] );
        
        if(!Utility.isEmpty(tempArr2[2])){
          //update workflow record, reset the "<select a submitter>"
          if ("-1".equals(tempArr2[2])) {
            buffer.append(tempArr[2]);
          
          //dispaly workflow record & submitter  
          } else {
          	EmailRuleEngineHandle handle = new EmailRuleEngineHandle();
          	buffer.append(this.getSelectSubmitter(handle.getUserFullNameByUserID(new Integer(tempArr2[2])), tmpObj ) );
          }
        }
        buffer.append("&nbsp;&nbsp;&nbsp;&nbsp;<a href=\'#\' onclick=\'removeAction(" + tmpObj + ")\'>[X]</a>");
        buffer.append("<br>");
        
        j++;     
      }  
    }       
    
    condSeq++;
        
    //================================
    
    //add the last action
    if(!Utility.isEmpty(actionDescArr[0])){
      if (!actionDescHt.isEmpty()) {        
        buffer.append(AND + "&nbsp;");        
      }
      buffer.append(actionDescArr[0] + "&nbsp;&nbsp;");
    }
    
    if( !Utility.isEmpty(actionDescArr[1]) && Utility.isEmpty(actionDescArr[2]) ){
      buffer.append(actionDescArr[1] + "&nbsp;&nbsp;");
    
    } else if ( !Utility.isEmpty(actionDescArr[1]) && !Utility.isEmpty(actionDescArr[2]) ){
      //init WorkflowList Hashtable        
      String[] workflowArr = TextUtility.splitString(workflowList, SPILT_2);
      for (int n = 0; n < workflowArr.length; n++) {
        String[] tmpArr = TextUtility.splitString(workflowArr[n], SPILT_1);
        workflowListHt.put(tmpArr[0], tmpArr[1]);
      }        
      buffer.append(this.generateWorkflowDiv(workflowList, (String)workflowListHt.get(actionValueArr[1]), "-1" ) );
      
    } 
        
    if(!Utility.isEmpty(actionDescArr[2])){
      buffer.append(actionDescArr[2] + "&nbsp;&nbsp;");
    }
    
    return buffer.toString();
  }
  
  /**
   * get action div
   * @param language
   * @return String
   */
  public String getActionDiv(String language){
    actionDescArr[0] = this.generateActionDiv(language);  
    return this.getOldAction();    
  }
  //bill add for EIP-1442
  public String getActionDiv(String language,String ruleType){
	this.ruleType=ruleType;
	return getActionDiv(language);   
  }
  /**
   * get action category
   * @param value
   * @param description
   * @param language
   * @param workflowList
   * @return String
   */
  public String getActionCategory(String value, String description, String language, String workflowList){
    actionValueArr[0] = value;
    actionDescArr[0] = description;  
    
    if (MaintEmailArchiveRuleForm.ACTION_NOTIFY_ME.equals( actionValueArr[0] )){
      actionDescArr[1] = this.generateNotifyDiv(language, SELECT_NOTIFY, "-1"); 
      
    } else if (MaintEmailArchiveRuleForm.ACTION_RUTE_TO.equals( actionValueArr[0] )){ 
      actionDescArr[1] = this.getFolderPicker("", "", "-1"); 
      
    } else if (MaintEmailArchiveRuleForm.ACTION_START_WORKFLOW.equals( actionValueArr[0] )){
      actionDescArr[1] = this.generateWorkflowDiv(workflowList, SELECT_WORKFLOW, "-1"); 
    }
         
    return this.getOldAction();
  }
  
  /**
   * add a new action
   * @param value
   * @param description
   * @param ID
   * @return String
   */
  public String addAction(String value, String description, String ID){
    if ("-1".equals(ID)) {
  	  actionValueArr[1] = value;
  	  actionDescArr[1] = description;  	    
  	  this.recordAction();
      
    } else {      
      String[] tmpArr = (String[])this.actionValueHt.get(ID);
      tmpArr[1] = value;
      this.actionValueHt.remove(ID);
      this.actionValueHt.put(ID, tmpArr);
      
      String[] tmpArr2 = (String[])this.actionDescHt.get(ID);
      tmpArr2[1] = description;
      this.actionDescHt.remove(ID);
      this.actionDescHt.put(ID, tmpArr2);
    }
  	return this.getOldAction();
  }
  
  /**
   * record the action
   */
  private void recordAction(){
    String[] tmpValueArr = new String[3];
    String[] tmpDescArr = new String[3];
    
    tmpValueArr[0] = actionValueArr[0];
    tmpValueArr[1] = actionValueArr[1];   
    tmpValueArr[2] = actionValueArr[2];    
    
    tmpDescArr[0] = actionDescArr[0];
    tmpDescArr[1] = actionDescArr[1]; 
    tmpDescArr[2] = actionDescArr[2]; 
    
    if ( !this.hasSameObject(actionValueHt, this.RULE_ITEM_TOTAL, tmpValueArr)) {
    	condSeq++; 
    	actionValueHt.put(String.valueOf(condSeq), tmpValueArr);        
    	actionDescHt.put(String.valueOf(condSeq), tmpDescArr);
    }
    
    actionValueArr = new String[3];
    actionDescArr = new String[3];
  }
    
  /**
   * new a action
   * @param language
   * @return String
   */
  public String newAction(String language){
    actionDescArr[0] = this.generateActionDiv(language);    
    return this.getOldAction();
  }
  
  /**
   * remove a action
   * @param itemSeq
   * @return String
   */
  public String removeAction(String itemSeq){
    StringBuffer buff = new StringBuffer();
    actionValueHt.remove(itemSeq);
    actionDescHt.remove(itemSeq);
    
    buff.append(this.getOldAction());
    
    return buff.toString();
  }
  
  /**
   * init some objects
   * @param contextPath
   * @param language
   * @param workflowList
   * @return String
   */
  public String initObjects(String contextPath, String language, String workflowList){
    this.locale = Utility.getLocaleByString(language);
    this.language = language;
    this.workflowList = workflowList;
    condSeq = 0;
    condValueHt = new Hashtable();
    condDescHt = new Hashtable();    
    actionValueHt = new Hashtable();
    actionDescHt = new Hashtable();
    
    condValueArr = new String[4];
    condDescArr = new String[4];    
    actionValueArr = new String[3];
    actionDescArr = new String[3];
    
    //init condition Hashtable
    conditionHt = (Hashtable)getConditionHashtable(locale);

    //init optionType1 Hashtable
    optionType1Ht.put(RuleOperationConstant.PREDICATE_TYPE_EQUAL_IGNORE_CASE, MessageResourcesFactory.getMessage(locale, "email_archive.rule.is") );
    optionType1Ht.put(RuleOperationConstant.PREDICATE_TYPE_CONTAINES, MessageResourcesFactory.getMessage(locale, "email_archive.rule.contains") ); 
    optionType1Ht.put(RuleOperationConstant.PREDICATE_TYPE_CONTAINES_EQUALS, MessageResourcesFactory.getMessage(locale, "email_archive.rule.is") );
    optionType1Ht.put(RuleOperationConstant.PREDICATE_TYPE_CONTAINES_ARRAY, MessageResourcesFactory.getMessage(locale, "email_archive.rule.contains") );
    
    //init optionType2 Hashtable
//    optionType2Ht.put(RuleOperationConstant.PREDICATE_TYPE_EQUAL_IGNORE_CASE, MessageResourcesFactory.getMessage(locale, "email_archive.rule.is" ) );
    optionType2Ht.put(RuleOperationConstant.PREDICATE_TYPE_CONTAINES_ARRAY, MessageResourcesFactory.getMessage(locale, "email_archive.rule.contains") );
    optionType2Ht.put(RuleOperationConstant.PREDICATE_TYPE_CONTAINES_EQUALS, MessageResourcesFactory.getMessage(locale, "email_archive.rule.is") );

    //init actionCategoryItem Hashtable
    actionCategoryItemHt = (Hashtable)getActionCategoryHashtable(locale);
    
    //init notifyItem Hashtable
    notifyItemHt.put(UpdateAlert.EMAIL_NOTIFICATION, MessageResourcesFactory.getMessage(locale, "email_archive.rule.by_email") );
    notifyItemHt.put(UpdateAlert.SYSTEM_NOTIFICATION, MessageResourcesFactory.getMessage(locale, "email_archive.rule.by_system_message" ) );
    notifyItemHt.put(UpdateAlert.EMAIL_NOTIFICATION + RuleOperationConstant.SPLIT_STRING + UpdateAlert.SYSTEM_NOTIFICATION, MessageResourcesFactory.getMessage(locale, "email_archive.rule.by_email_system") );
        
    this.CONTEXT_PATH = contextPath;
    initConstants(language);
    return "";
  }

  public Map getActionCategoryHashtable(Locale locale) {
    Hashtable actionCategoryItemHt = new Hashtable();
    actionCategoryItemHt.put(MaintEmailArchiveRuleForm.ACTION_NOTIFY_ME, MessageResourcesFactory.getMessage(locale, "email_archive.rule.notyfy_me") );
    actionCategoryItemHt.put(MaintEmailArchiveRuleForm.ACTION_RUTE_TO, MessageResourcesFactory.getMessage(locale, "email_archive.rule.route_to") );
    actionCategoryItemHt.put(MaintEmailArchiveRuleForm.ACTION_START_WORKFLOW, MessageResourcesFactory.getMessage(locale, "email_archive.rule.start_workflow") );
    return actionCategoryItemHt;
  }

  public Map getConditionHashtable(Locale locale) {
    Hashtable conditionHt=new Hashtable();
    conditionHt.put(MaintEmailArchiveRuleForm.CRITERION_SUBJECT, MessageResourcesFactory.getMessage(locale, "email_archive.rule.subject") );
    conditionHt.put(MaintEmailArchiveRuleForm.CRITERION_MESSAGE, MessageResourcesFactory.getMessage(locale, "email_archive.rule.message") );
    conditionHt.put(MaintEmailArchiveRuleForm.CRITERION_MESSAGE_BODY, MessageResourcesFactory.getMessage(locale, "email_archive.rule.messagebody"));
    conditionHt.put(MaintEmailArchiveRuleForm.CRITERION_EMAILTO, MessageResourcesFactory.getMessage(locale, "email_archive.rule.to") ) ;
    conditionHt.put(MaintEmailArchiveRuleForm.CRITERION_EMAILCC, MessageResourcesFactory.getMessage(locale, "email_archive.rule.cc") );
    conditionHt.put(MaintEmailArchiveRuleForm.CRITERION_EMAILFROM, MessageResourcesFactory.getMessage(locale, "email_archive.rule.from") );
    return conditionHt;
  }
  
  
  /**
   * display condition plus
   * @return
   */
  public String displayCondPlus(){
    if (this.displayCondPlus) {
      return GlobalConstant.TRUE;
    } else {
      return GlobalConstant.FALSE;
    } 
  }
  
  /**
   * get conditon value
   * @return String
   */
  public String getConditionValue(){
    StringBuffer buffer = new StringBuffer();
    
    if ( !Utility.isEmpty(condValueArr[0]) ) {
      this.recordCondition();
    }
    
    int i = 0;
    for (int n = 0; n < this.RULE_ITEM_TOTAL; n++) {
      Object tmpObj = String.valueOf(n);
      if (condValueHt.containsKey(tmpObj)) {
      	String[] tempArr = (String[])(condValueHt.get(tmpObj));
      	
      	if (i > 0) {
      		buffer.append(SPILT_2); 
      	}
      	
        //handle the email to/cc/form
        if (MaintEmailArchiveRuleForm.CRITERION_EMAILTO.equals(tempArr[0])
            || MaintEmailArchiveRuleForm.CRITERION_EMAILCC.equals(tempArr[0])
            || MaintEmailArchiveRuleForm.CRITERION_EMAILFROM.equals(tempArr[0]) ) {
          buffer.append(tempArr[0] + SPILT_1+ tempArr[1] + SPILT_1);
          String tempStr = "";
          if (!Utility.isEmpty(tempArr[2]) && !EMAIL_CHAR.equals(tempArr[2])) {
            tempStr = tempArr[2];
          }
          
          if (!Utility.isEmpty(tempArr[3])){
            if (!Utility.isEmpty(tempStr)) {
              tempStr += RuleOperationConstant.SPLIT_COMMA;
            }
            tempStr += tempArr[3];
          }
          
          buffer.append(tempStr);
        
        } else {
          buffer.append(tempArr[0] + SPILT_1+ tempArr[1] + SPILT_1 + tempArr[2]);
        }
      	
        
        
        
      	i++;   
      }
    }
    
    return buffer.toString();
  }
  
  /**
   * get action value
   * @return
   */
  public String getActionValue(){
    StringBuffer buffer = new StringBuffer();
    
    int i = 0;
    for (int n = 0; n < this.RULE_ITEM_TOTAL; n++) {      
      Object tmpObj = String.valueOf(n);
      if (actionValueHt.containsKey(tmpObj)) {
        String[] tempArr = (String[])(actionValueHt.get(tmpObj));
        
        if (i > 0) {
          buffer.append(SPILT_2); 
        }
              
        if(MaintEmailArchiveRuleForm.ACTION_START_WORKFLOW.equals( tempArr[0] )){
          buffer.append(tempArr[0] + SPILT_1+ tempArr[1] + RuleOperationConstant.SPLIT_STRING + tempArr[2] );   
        } else {
          buffer.append(tempArr[0] + SPILT_1+ tempArr[1] );    
        }
            
        i++;      
      }
    }  
      
    return buffer.toString();
  }
  
  /**
   * get detail deacription 
   * @param isAnd
   * @return String 
   */
  public String getDetailDescription(boolean isAnd){
    StringBuffer buffer = new StringBuffer();
    
    buffer.append(IF + "<br> ");
        
    //get the condition description          
    int i = 0;
    for (int n = 0; n < RULE_ITEM_TOTAL; n++) {
      Object tmpObj = String.valueOf(n);   
      if (condValueHt.containsKey(tmpObj)) {
        buffer.append("&nbsp;&nbsp;&nbsp;&nbsp;");
        String[] tempArr = (String[])(condValueHt.get(tmpObj));
        
        if (i > 0 && isAnd) {
        	buffer.append(AND + " ");
        	
        } else if (i>0 && !isAnd){
        	buffer.append(OR + " ");
        }
        i++;
        
        buffer.append(conditionHt.get(tempArr[0])); 
        if ( optionType1Ht.containsKey(tempArr[1]) ) {
        	buffer.append(" " + optionType1Ht.get(tempArr[1]));
        }
        if(MaintEmailArchiveRuleForm.CRITERION_SUBJECT.equals(tempArr[0]) ||
        		MaintEmailArchiveRuleForm.CRITERION_MESSAGE_BODY.equals(tempArr[0])  ) {
        	buffer.append(" [" + tempArr[2] + "]");         
        	
        } else if (MaintEmailArchiveRuleForm.CRITERION_EMAILTO.equals(tempArr[0])
        		|| MaintEmailArchiveRuleForm.CRITERION_EMAILCC.equals(tempArr[0])
						|| MaintEmailArchiveRuleForm.CRITERION_EMAILFROM.equals(tempArr[0]) ) {
        	
          String tempStr = "";
          //get the email address
          if (!Utility.isEmpty(tempArr[2]) && !EMAIL_CHAR.equals(tempArr[2])) {
            tempStr = tempArr[2];
          }
          
          //get the userpicker display name 
          if (!Utility.isEmpty(tempArr[3])) {            
            EmailRuleEngineHandle handle = new EmailRuleEngineHandle();
            if (!Utility.isEmpty(tempStr)) {
              tempStr += RuleOperationConstant.SPLIT_BIAS;
            }
            tempStr +=  handle.getUserPickerString(tempArr[3]);            
          }
          buffer.append(" [" + tempStr + "]");  
        	
        } else if (MaintEmailArchiveRuleForm.CRITERION_MESSAGE.equals(tempArr[0])) {
        	buffer.append(" " + HAS_ATTACHMENT);
        }
        buffer.append("<br>");
      }
    } 
    
    
    buffer.append(" <br>" + THEN + "<br> ");
        
    //get the action description    
    int j = 0;
    for (int n = 0; n < RULE_ITEM_TOTAL; n++) {      
      Object tmpObj = String.valueOf(n);
      if (actionValueHt.containsKey(tmpObj)) {
        buffer.append("&nbsp;&nbsp;&nbsp;&nbsp;");
        if (j > 0) {
          buffer.append(AND + " ");
        }
        j++;
        
      	String[] tempArr = (String[])(actionValueHt.get(tmpObj));       	
      	buffer.append(actionCategoryItemHt.get(tempArr[0]) );      	
      	if (MaintEmailArchiveRuleForm.ACTION_NOTIFY_ME.equals( tempArr[0] )){
      		buffer.append(" " + this.notifyItemHt.get(tempArr[1]) );        
      		
      	} else if (MaintEmailArchiveRuleForm.ACTION_RUTE_TO.equals( tempArr[0] )){
      		String[] valueArr = TextUtility.splitString(tempArr[1], RuleOperationConstant.SPLIT_STRING);
      		EmailRuleEngineHandle handle = new EmailRuleEngineHandle();
      		buffer.append(" [" +  handle.getFolderPath(valueArr[0], valueArr[1]) + "]" ); 
      		
      	} else if (MaintEmailArchiveRuleForm.ACTION_START_WORKFLOW.equals( tempArr[0] )){
      		//init WorkflowList Hashtable      
      		EmailRuleEngineHandle handle = new EmailRuleEngineHandle();        
      		buffer.append(" [" + handle.getWorfklowCodeByWorkflowRecordID( new Integer(tempArr[1])) + "]");
          buffer.append(" " + BY + " [" + handle.getUserFullNameByUserID(new Integer(tempArr[2]) ) + "]");
      	}
      	buffer.append("<br>"); 
      }
    }   
    
    return buffer.toString();
  }
  
  /**
   * get condition string
   * @param conditionStr
   * @param isAnd
   * @return String
   */
  public String getConditionString(String conditionStr, boolean isAnd){    
    String[] condArr = TextUtility.splitString(conditionStr, SPILT_2);
    for (int i = 0; i < condArr.length; i++) {
      String [] tempArr = new String[4];
      String[] array = TextUtility.splitString(condArr[i], SPILT_1);
      tempArr[0] = array[0];
      tempArr[1] = array[1];
      tempArr[2] = array[2];
      tempArr[3] = array[2]; //this is not an error.
      
      String[] tempArr2 = new String[4];
      tempArr2[0] = (String)conditionHt.get(tempArr[0]);      
            
      condSeq++;
      
      if(MaintEmailArchiveRuleForm.CRITERION_SUBJECT.equals(tempArr[0]) ||
         MaintEmailArchiveRuleForm.CRITERION_MESSAGE_BODY.equals(tempArr[0])  ) {
        tempArr2[1] = (String)optionType1Ht.get(tempArr[1]);
        tempArr2[2] = this.getTextBox(tempArr[2], String.valueOf(condSeq), false ); 
        tempArr2[3] = null;
        tempArr[3] = null;

      } else if (MaintEmailArchiveRuleForm.CRITERION_EMAILTO.equals(tempArr[0])
          || MaintEmailArchiveRuleForm.CRITERION_EMAILCC.equals(tempArr[0])
          || MaintEmailArchiveRuleForm.CRITERION_EMAILFROM.equals(tempArr[0]) ) {      
        
        String[] optionArr = TextUtility.splitString(tempArr[2], RuleOperationConstant.SPLIT_COMMA);        
        if (optionArr[0].indexOf(RuleOperationConstant.SPLIT_COLON) == -1 ) {
          tempArr[2] = optionArr[0];
          if (tempArr[3].length() > tempArr[2].length()) {
            tempArr[3] = tempArr[3].substring(tempArr[2].length() + 1);
          } else {
            tempArr[3] = null;  
          }
          
        } else {
          tempArr[2] = EMAIL_CHAR;  
        }        
        
        tempArr2[1] = (String)optionType1Ht.get(tempArr[1]);
        tempArr2[3] = this.getUserPicker(tempArr[3], String.valueOf(condSeq));
      
      } else if (MaintEmailArchiveRuleForm.CRITERION_MESSAGE.equals(tempArr[0])) {
        tempArr2[1] = HAS_ATTACHMENT;
        tempArr2[2] = "&nbsp;";
      }
      
      condValueHt.put(String.valueOf(condSeq), tempArr);      
      condDescHt.put(String.valueOf(condSeq), tempArr2);
    }    
    
    return this.getOldCondition(isAnd);
  }
  
  /**
   * get action String
   * @param actionStr
   * @param language
   * @param workflowList
   * @return String
   */
  public String getActionString(String actionStr, String language, String workflowList){
    String[] actionArr = TextUtility.splitString(actionStr, SPILT_2);
    for (int i = 0; i < actionArr.length; i++) {
      String [] tempArr = new String[3];
      String [] valueArrary = TextUtility.splitString(actionArr[i], SPILT_1);
      tempArr[0] = valueArrary[0];
      tempArr[1] = valueArrary[1];
      
      String[] tempArr2 = new String[3];      
      tempArr2[0] = (String)actionCategoryItemHt.get(tempArr[0]);
      
      condSeq++;
      if (MaintEmailArchiveRuleForm.ACTION_NOTIFY_ME.equals( tempArr[0] )){
        tempArr2[1] = this.generateNotifyDiv(language, (String)this.notifyItemHt.get(tempArr[1]), String.valueOf(condSeq) ); 
        
      } else if (MaintEmailArchiveRuleForm.ACTION_RUTE_TO.equals( tempArr[0] )){
        String[] valueArr = TextUtility.splitString(tempArr[1], RuleOperationConstant.SPLIT_STRING);        
        tempArr2[1] = this.getFolderPicker(valueArr[0], valueArr[1], String.valueOf(condSeq) ); 
        
      } else if (MaintEmailArchiveRuleForm.ACTION_START_WORKFLOW.equals( tempArr[0] )){
        //init WorkflowList Hashtable        
        String[] workflowArr = TextUtility.splitString(workflowList, SPILT_2);
        for (int j = 0; j < workflowArr.length; j++) {
          String[] tmpArr = TextUtility.splitString(workflowArr[j], SPILT_1);
          workflowListHt.put(tmpArr[0], tmpArr[1]);
        }  
        
        if (tempArr[1].indexOf(RuleOperationConstant.SPLIT_STRING) > -1 ) {
          String workflowRecordID = tempArr[1].substring(0, tempArr[1].indexOf(RuleOperationConstant.SPLIT_STRING) );
          String userRecordID = tempArr[1].substring(tempArr[1].indexOf(RuleOperationConstant.SPLIT_STRING) + 1 );
          
          tempArr[1] = workflowRecordID;
          tempArr[2] = userRecordID;
          
          //get the workflow list
          tempArr2[1] = this.generateWorkflowDiv(workflowList, (String)workflowListHt.get(workflowRecordID), String.valueOf(condSeq) );
        }
        
         
      }      
      
      actionValueHt.put(String.valueOf(condSeq), tempArr);      
      actionDescHt.put(String.valueOf(condSeq), tempArr2);
    }
    
    return this.getOldAction();
 
  }
  
  /**
   * change text box
   * @param isAnd
   * @param ID
   * @return String
   */
  public String changeTextBox(boolean isAnd, String ID){ 
  	String[] tmpArr = (String[])this.condValueHt.get(ID);  	
  	String[] tmpArr2 = (String[])this.condDescHt.get(ID);
  	tmpArr2[2] = this.getTextBox(tmpArr[2], ID, true);
  	
  	this.condDescHt.remove(ID);
  	this.condDescHt.put(ID, tmpArr2);    
    this.changeTextBoxID = ID;
    return this.getOldCondition(isAnd);
  }
  
  /**
   * check rule
   * @return String
   */
  public String checkRule(){
    String error = "";
    
    if (condValueHt.isEmpty() && Utility.isEmpty(condValueArr[0]) ) {
      error = "A"; //At least one condiction should be added
      return error;
    }        
    
    if (!Utility.isEmpty(condValueArr[0])) {
      if (Utility.isEmpty(condValueArr[1])) {
        return "C"; //Rule conditon is not integrated
      }
      if (!MaintEmailArchiveRuleForm.CRITERION_MESSAGE.equals(condValueArr[0]) &&
          Utility.isEmpty(condValueArr[2])) {
        return "C"; //Rule conditon is not integrated
      }      
    }   
       
    Set keySet = condValueHt.keySet();
    Iterator iterator = keySet.iterator();
    while (iterator.hasNext()){
      Object obj = iterator.next();
      String[] tempArr = (String[])condValueHt.get(obj);
      if (MaintEmailArchiveRuleForm.CRITERION_EMAILTO.equals(tempArr[0])
          || MaintEmailArchiveRuleForm.CRITERION_EMAILCC.equals(tempArr[0])
          || MaintEmailArchiveRuleForm.CRITERION_EMAILFROM.equals(tempArr[0]) ) {        
        if ( EMAIL_CHAR.equals(tempArr[2]) && Utility.isEmpty(tempArr[3])) {
          return "C"; //Rule conditon is not integrated
        }
      }
      
    }
    
    if (actionValueHt.isEmpty() && Utility.isEmpty(actionValueArr[0]) ) {
      return "B"; //At least one action should be added.
    }
    
    if (!Utility.isEmpty(actionValueArr[0])) {
      if (Utility.isEmpty(actionValueArr[1])) {
        return "D"; //Rule action is not integrated
      
      //if select a workflow not select the submitter.  
      } else if (MaintEmailArchiveRuleForm.ACTION_START_WORKFLOW.equals( actionValueArr[0] )) {
        if (Utility.isEmpty(actionValueArr[2]) || "-1".equals(actionValueArr[2])) {
          return "D"; //Rule action is not integrated
        }
      }
    }
    
    return error;  
  }  

  private void initConstants(String language){
    this.locale = Utility.getLocaleByString(language);
    AND = MessageResourcesFactory.getMessage(locale,"email_archive.rule.and");
    OR = MessageResourcesFactory.getMessage(locale,"email_archive.rule.or");
    IF = MessageResourcesFactory.getMessage(locale,"email_archive.rule.if");
    THEN = MessageResourcesFactory.getMessage(locale,"email_archive.rule.then");
   
    SELECT_CONDITION = "&lt; " + MessageResourcesFactory.getMessage(locale, "email_archive.rule.select_a_conditon") + " &gt;";
    
    SELECT_JUDGEMENT = "&lt; " + MessageResourcesFactory.getMessage(locale, "email_archive.rule.select_a_judgement") + " &gt;";
        
    SELECT_ACTION = "&lt; " + MessageResourcesFactory.getMessage(locale, "email_archive.rule.select_a_action") + " &gt;";
    SELECT_NOTIFY = "&lt; " + MessageResourcesFactory.getMessage(locale, "email_archive.rule.select_a_notify_way") + " &gt;";
    SELECT_TARGET = "&lt; " + MessageResourcesFactory.getMessage(locale, "email_archive.rule.select_a_target") + " &gt;";
    SELECT_WORKFLOW = "&lt; " + MessageResourcesFactory.getMessage(locale, "email_archive.rule.select_a_workflow") + " &gt;";
    SELECT_USER = "<img src=\"" + this.CONTEXT_PATH + "/theme/pref1/img/common/IconPopupSearch.gif\" align=\"absmiddle\" border=\"0\">" ;   
    
    SELECT_FOLDER_PATH = "&lt; " + MessageResourcesFactory.getMessage(locale, "email_archive.rule.select_a_folder") + " &gt;";
    SELECT_SUBMITTER = "&lt; " + MessageResourcesFactory.getMessage(locale, "email_archive.rule.select_a_submitter") + " &gt;";
    
    BY = MessageResourcesFactory.getMessage(locale, "email_archive.rule.on_behalf_of");
    
    HAS_ATTACHMENT = MessageResourcesFactory.getMessage(locale,"email_archive.rule.has_attachment");
    CONTAINS = MessageResourcesFactory.getMessage(locale,"email_archive.rule.contains");
    selectJudgement = "&nbsp;&nbsp;<A onclick=\"displayDiv(\'judgementDiv\', true)\" onMouseOut=\"return nd();\"\' href=\'#\'><font color=\'blue\'>" + SELECT_JUDGEMENT + "</font></A>";
  }
  
  /**
   * get select submitter string
   * @param description
   * @param ruleID
   * @return String
   */
  private String getSelectSubmitter(String description, String ruleID){
    StringBuffer buffer = new StringBuffer();
    buffer.append(BY);
    buffer.append("&nbsp;<a href=\"javascript:void(0);\" onclick=\"hideDivs(\'\');return OpenCenteredPopup(\'" + CONTEXT_PATH + "/user/PopupUserRecord.do?mode=L&property=submitter&form=listWorkflowMonitoringForm&pageFlag=&isMulitple=&mulitpleValue=&index=null&noHiddenValue=true&ruleID=" + ruleID + "\', \'DCIVisionPopupUser\', 700, 500, \'scrollbars=yes,resizable=yes\');\">");
    buffer.append("<font color=\'blue\'>" + description + "</font>");
    buffer.append(" </a>");
    
    return buffer.toString();
  }
  
  /**
   * get a submitter
   * @param value
   * @param description
   * @param ID
   * @return
   */
  public String getSubmitter(String value, String description, String ID){
    if ("-1".equals(ID)) {
      actionValueArr[1] = value;
      actionDescArr[1] = description;
      actionDescArr[2] = this.getSelectSubmitter(SELECT_SUBMITTER, ID);  
      //this.recordAction();
      
    } else {      
      String[] tmpArr = (String[])this.actionValueHt.get(ID);
      tmpArr[1] = value;
      tmpArr[2] = "-1";
      this.actionValueHt.remove(ID);
      this.actionValueHt.put(ID, tmpArr);
      
      String[] tmpArr2 = (String[])this.actionDescHt.get(ID);
      tmpArr2[1] = description;
      tmpArr2[2] = this.getSelectSubmitter(SELECT_SUBMITTER, ID);  
      this.actionDescHt.remove(ID);
      this.actionDescHt.put(ID, tmpArr2);
    }
    
    return this.getOldAction();
  }
  
  /**
   * add a submitter
   * @param value
   * @param description
   * @param ID
   * @return String
   */
  public String addSubmitter(String value, String description, String ID){
    if ("-1".equals(ID)) {
      actionValueArr[2] = value;
      actionDescArr[2] = description;   
      this.recordAction();
      
    } else {      
      String[] tmpArr = (String[])this.actionValueHt.get(ID);
      tmpArr[2] = value;
      this.actionValueHt.remove(ID);
      this.actionValueHt.put(ID, tmpArr);
      
      String[] tmpArr2 = (String[])this.actionDescHt.get(ID);
      tmpArr2[2] = description;
      this.actionDescHt.remove(ID);
      this.actionDescHt.put(ID, tmpArr2);
    }
    return this.getOldAction();
  }
  
  /**
   * check permission
   * @param userRecordID
   * @param description
   * @param ruleID
   * @return String
   */
  public String checkPermission(String userRecordID, String description, String ruleID){
    //check execute permission
    EmailRuleEngineHandle handle = new EmailRuleEngineHandle();
    Integer workflowRecordID = null;
    
    //get the workflowRecordID
    if("-1".equals(ruleID)){
      workflowRecordID = new Integer(actionValueArr[1]);
    } else {
      String[] tempArr = (String[])this.actionValueHt.get(ruleID);
      workflowRecordID = new Integer(tempArr[1]);
    }
    
    //check the permission
    boolean permission = handle.checkPermissionByWorkflowRecordIDUserRecordID(workflowRecordID, new Integer(userRecordID));  
    if (permission) {
    	return this.addSubmitter(userRecordID, description, ruleID);
      
    } else {      
    	return GlobalConstant.FALSE + SPILT_1  + MessageResourcesFactory.getMessage(locale, "email_archive.rule.select_user_no_right_start_workflow", description);
    }
  }
  
  /**
   * merge the same object in the hashtable.
   * @param hashtable
   * @param total
   */
  private void mergeSameObject(Hashtable hashtable, int total){
    boolean equals = true;
    for(int i = 0; i < total; i++){
      if(hashtable.containsKey(String.valueOf(i))){
        Object object = hashtable.get(String.valueOf(i));
        String[] array = (String[])object;
        
        for(int j = i + 1; j < total; j++){          
         if (hashtable.containsKey(String.valueOf(j))){          
            Object object2 = hashtable.get(String.valueOf(j));
            String[] array2 = (String[])object2;
            
            equals = true;
            for (int k = 0; k < array.length; k++) {
              if ( array[k] != null && !array[k].equals(array2[k]) ) {
                equals = false;
                break;
              }
            }           
            if (equals) { 
              hashtable.remove(String.valueOf(j));
              break;
            }
         }
        }        
        if (equals) { 
          break; 
        }
      }
    }
    //Clarify repeated notify method
    this.clarifyNotify(hashtable, total);
  }
  
  /**
   * check same object
   * @param hashtable
   * @param total
   * @param array2
   * @return
   */
  private boolean hasSameObject(Hashtable hashtable, int total, String[] array2){
    if (hashtable.isEmpty()) {
      return false;
    }
    boolean equals = true;
    for(int i = 0; i < total; i++){
      if(hashtable.containsKey(String.valueOf(i))){
        Object object = hashtable.get(String.valueOf(i));
        String[] array = (String[])object;
            
        equals = true;
        for (int k = 0; k < array.length; k++) {
        	if ( array2[k] != null && !array2[k].equals(array[k]) ) {
        		equals = false;
            break;
        	}
        }
                
        if (equals) {
          break;        	
        }
        
      }
    }
    //Clarify repeated notify method
    this.clarifyNotify(hashtable, total);
    return equals;
  }
  
  /**
   * clarify repeated notify method
   * @param hashtable
   * @param total
   */
  private void clarifyNotify(Hashtable hashtable, int total){    
    String [] notifyItemArr = new String[3];    
    int j = 0;    
    boolean hasEmailMessage = false;
    String emailMessageNo = "";
    
    //filty the MaintEmailArchiveRuleForm.ACTION_NOTIFY_ME action
    for(int i = 0; i < total; i++){
      if(hashtable.containsKey(String.valueOf(i))){
        Object object = hashtable.get(String.valueOf(i));
        String[] array = (String[])object;
        
        if (MaintEmailArchiveRuleForm.ACTION_NOTIFY_ME.equals(array[0])) {
          notifyItemArr[j] = String.valueOf(i);          
          if ( (UpdateAlert.EMAIL_NOTIFICATION + RuleOperationConstant.SPLIT_STRING + UpdateAlert.SYSTEM_NOTIFICATION).equals(array[1])) {
            hasEmailMessage = true;  
            emailMessageNo = notifyItemArr[j];
          }          
          
          j++;
        }
      }
    }   
     
    //remove the repeated notify method.
    for (int k = 0; hasEmailMessage && k < notifyItemArr.length; k++) {
      if ( !emailMessageNo.equals(notifyItemArr[k]) ) {
        hashtable.remove(String.valueOf(notifyItemArr[k]));
      } 
    }
  }
  
}
